home *** CD-ROM | disk | FTP | other *** search
/ Nebula 1 / Nebula One.iso / Graphics / Multimedia / MPlay / mpeg_play2.0 / main.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-12-13  |  9.6 KB  |  454 lines

  1. /*
  2.  * Copyright (c) 1992 The Regents of the University of California.
  3.  * All rights reserved.
  4.  * 
  5.  * Permission to use, copy, modify, and distribute this software and its
  6.  * documentation for any purpose, without fee, and without written agreement is
  7.  * hereby granted, provided that the above copyright notice and the following
  8.  * two paragraphs appear in all copies of this software.
  9.  * 
  10.  * IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR
  11.  * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
  12.  * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE UNIVERSITY OF
  13.  * CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  14.  * 
  15.  * THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES,
  16.  * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
  17.  * AND FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
  18.  * ON AN "AS IS" BASIS, AND THE UNIVERSITY OF CALIFORNIA HAS NO OBLIGATION TO
  19.  * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
  20.  */
  21.  
  22. /*
  23.      modified for real time playing of mpegs, pgriffin 
  24.  */
  25.  
  26. #include "video.h"
  27. #include "proto.h"
  28. #include "nextstep.h"
  29. #include <sys/types.h>
  30. #include <sys/param.h>
  31. #include <signal.h>
  32. #ifndef MIPS
  33. #include <netinet/in.h>
  34. #else
  35. #include <bsd/netinet/in.h>
  36. #endif
  37.  
  38. #include "util.h"
  39.  
  40. /* Define buffer length. */
  41.  
  42. #define BUF_LENGTH 80000
  43.  
  44. /* Function return type declarations */
  45. void usage();
  46.  
  47. /* External declaration of main decoding call. */
  48.  
  49. extern VidStream *mpegVidRsrc();
  50. extern VidStream *NewVidStream();
  51.  
  52. /* Global file pointer to incoming data. */
  53. FILE *input;
  54.  
  55. /* End of File flag. */
  56. static int EOF_flag = 0;
  57.  
  58. /* Loop flag. */
  59. int loopFlag = 0;
  60.  
  61. /* Quiet flag. */
  62. int quietFlag = 0;
  63.  
  64. /* Setjmp/Longjmp env. */
  65. jmp_buf env;
  66.  
  67. /* Display image on screen? */
  68. int noDisplayFlag = 0;
  69.  
  70. /* speed beyond real time Flag */
  71. unsigned char speedFlag = 0;
  72.  
  73. /* magnification Flag */
  74. float magFlag = 1.0;
  75.  
  76. /* the file name */
  77. unsigned char filename[MAXPATHLEN];
  78.  
  79. /* hold display until further window events */
  80. unsigned char holdFrame; 
  81. /* draw self flag */
  82. unsigned char drawFrame;
  83. /* speed in titlebar */
  84. unsigned char showSpeed;
  85. /* timing information */
  86. double frame_interval;    
  87. int frames_per_sec;
  88. /* rewind flag */
  89. unsigned char doRewind;
  90.  
  91. /* 
  92. /*
  93.  *--------------------------------------------------------------
  94.  *
  95.  * get_more_data --
  96.  *
  97.  *    Called by correct_underflow in bit parsing utilities to
  98.  *      read in more data.
  99.  *
  100.  * Results:
  101.  *    Input buffer updated, buffer length updated.
  102.  *      Returns 1 if data read, 0 if EOF, -1 if error.
  103.  *
  104.  * Side effects:
  105.  *      None.
  106.  *
  107.  *--------------------------------------------------------------
  108.  */
  109.  
  110. int 
  111. get_more_data(buf_start, max_length, length_ptr, buf_ptr)
  112.      unsigned int *buf_start;
  113.      int max_length;
  114.      int *length_ptr;
  115.      unsigned int **buf_ptr;
  116. {
  117.   
  118.   int length, num_read, i, request;
  119.   unsigned char *buffer, *mark;
  120.   unsigned int *lmark;
  121.  
  122.   if (EOF_flag) return 0;
  123.  
  124.   length = *length_ptr;
  125.   buffer = (unsigned char *) *buf_ptr;
  126.  
  127.   if (length > 0) {
  128.     memcpy((unsigned char *) buf_start, buffer, (length*4));
  129.     mark = ((unsigned char *) (buf_start + length));
  130.   }
  131.   else {
  132.     mark = (unsigned char *) buf_start;
  133.     length = 0;
  134.   }
  135.  
  136.   request = (max_length-length)*4;
  137.   
  138.   num_read = fread( mark, 1, request, input);
  139.  
  140.   /* Paulo Villegas - 26/1/1993: Correction for 4-byte alignment */
  141.   {
  142.     int num_read_rounded;
  143.     unsigned char *index;
  144.  
  145.     num_read_rounded = 4*(num_read/4);
  146.  
  147.     /* this can happen only if num_read<request; i.e. end of file reached */
  148.     if( num_read_rounded < num_read )
  149.       { 
  150.      num_read_rounded = 4*( num_read/4+1 );
  151.      /* fill in with zeros */
  152.      for( index=mark+num_read; index<mark+num_read_rounded; *(index++)=0 );
  153.      /* advance to the next 4-byte boundary */
  154.      num_read = num_read_rounded;
  155.       }
  156.   }
  157.   
  158.   if   (num_read < 0) {
  159.     return -1;
  160.   }
  161.   else if (num_read == 0) {
  162.     *buf_ptr = buf_start;
  163.     
  164.     /* Make 32 bits after end equal to 0 and 32
  165.        bits after that equal to seq end code
  166.        in order to prevent messy data from infinite
  167.        recursion.
  168.     */
  169.  
  170.     *(buf_start + length) = 0x0;
  171.     *(buf_start + length+1) = SEQ_END_CODE;
  172.  
  173.     EOF_flag = 1;
  174.     return 0;
  175.   }
  176.  
  177.   lmark = (unsigned int *) mark;
  178.  
  179.   num_read = num_read/4;
  180.  
  181.   for (i=0; i<num_read; i++) {
  182.     *lmark = htonl(*lmark);
  183.     lmark++;
  184.   }
  185.  
  186.   *buf_ptr = buf_start;
  187.   *length_ptr = length + num_read;
  188.  
  189.   return 1;
  190. }
  191.  
  192. /*
  193.  *--------------------------------------------------------------
  194.  *
  195.  * int_handler --
  196.  *
  197.  *    Handles Cntl-C interupts..
  198.  *
  199.  * Results:
  200.  *    None.
  201.  *
  202.  * Side effects:
  203.  *    None.
  204.  *
  205.  *--------------------------------------------------------------
  206.  */
  207. void
  208. int_handler()
  209. {
  210.   if (!quietFlag && loopFlag) {
  211.       fprintf(stderr, "\nDone!\n");
  212.   }
  213.  
  214. #ifdef ANALYSIS
  215.     if(loopFlag) PrintAllStats();
  216. #endif
  217.     if(loopFlag) PrintTimeInfo();
  218.  
  219.  
  220. if (curVidStream != NULL)
  221.     DestroyVidStream(curVidStream);
  222.   exit(1);
  223. }
  224.  
  225.  
  226. /*
  227.  *--------------------------------------------------------------
  228.  *
  229.  * main --
  230.  *
  231.  *    Parses command line, starts decoding and displaying.
  232.  *
  233.  * Results:
  234.  *    None.
  235.  *
  236.  * Side effects:
  237.  *    None.
  238.  *
  239.  *--------------------------------------------------------------
  240.  */
  241.  
  242. void
  243. main(argc, argv)
  244.      int argc;
  245.      char **argv;
  246. {
  247.  
  248.   char *name;
  249.   static VidStream *theStream;
  250.   int mark, firstLoop;
  251.   
  252.   /* used to control the frame display rate */
  253.       double ReadSysClock();
  254.       double next_time;    
  255.     int frame_ref;
  256.     unsigned char do_frame;
  257.     
  258.   firstLoop = 1;
  259.   mark = 1;
  260.   argc--;
  261.  
  262.   name = "";
  263.   input = stdin;
  264.   noDisplayFlag = 0;
  265.  
  266.   while (argc) {
  267.     if (strcmp(argv[mark], "-nop") == 0) {
  268.       TogglePFlag();
  269.       argc--; mark++;
  270.     } else if (strcmp(argv[mark], "-nob") == 0) {
  271.       ToggleBFlag();
  272.       argc--; mark++;
  273.     } else if (strcmp(argv[mark], "-display") == 0) {
  274.       name = argv[++mark];
  275.       argc -= 2; mark++;
  276.     } 
  277.     else if (strcmp(argv[mark], "-eachstat") == 0) {
  278.       argc--; mark++;
  279. #ifdef ANALYSIS
  280.       showEachFlag = 1;
  281. #else
  282.       fprintf(stderr, "To use -eachstat, recompile with -DANALYSIS in CFLAGS\n");
  283.       exit(1);
  284. #endif
  285.     }
  286.     else if (strcmp(argv[mark], "-quiet") == 0) {
  287.       argc--; mark++;
  288.       quietFlag = 1;
  289.     }
  290.     else if (strcmp(argv[mark], "-loop") == 0) {
  291.       argc--; mark++;
  292.       loopFlag = 1;
  293.     }
  294.     else if (strcmp(argv[mark], "-no_display") == 0) {
  295.       argc--; mark++;
  296.       noDisplayFlag = 1;
  297.     }
  298.     else if (strcmp(argv[mark], "-fastest") == 0) {
  299.       argc--; mark++;
  300.       speedFlag = 1;
  301.     }
  302.     else if (strcmp(argv[mark], "-mag") == 0){
  303.       argc--; mark++;
  304.         if(sscanf(argv[mark], "%f", &magFlag) >= 0) {argc--;mark++;}
  305.     }
  306.     
  307.     else if (argv[mark][0] == '-') {
  308.       fprintf(stderr, "Un-recognized flag %s\n",argv[mark]);
  309.       usage(argv[0]);
  310.     }
  311.     else {
  312.       input = fopen(argv[mark], "r");
  313.       if (input == NULL) {
  314.             fprintf(stderr, "Could not open file %s\n", argv[mark]);
  315.             usage(argv[0]);      
  316.       }
  317.       if(input != NULL) strcpy(filename, argv[mark]);
  318.       argc--; mark++;
  319.     }
  320.   }
  321.  
  322.   signal(SIGINT, int_handler);
  323.  
  324.   init_tables();  
  325.   InitColorDither();
  326.  
  327.   if (setjmp(env) != 0) {
  328.  
  329.     DestroyVidStream(theStream);
  330.  
  331.     rewind(input);
  332.  
  333.     EOF_flag = 0;
  334.     curBits = 0;
  335.     bitOffset = 0;
  336.     bufLength = 0;
  337.     bitBuffer = NULL;
  338.     totNumFrames = 0;
  339.     firstLoop = 0;
  340.  
  341. #ifdef ANALYSIS 
  342.     init_stats();
  343. #endif
  344.  
  345.   }
  346.  
  347.   doRewind = 0;
  348.   
  349.   if(!quietFlag && firstLoop) printf("Initializing... ");
  350.   else if(firstLoop) printf(" "); /* wish I didn't have to do this.
  351.                                       otherwise, colors are wrong??? */
  352.   
  353.   if((theStream = NewVidStream(BUF_LENGTH)) == NULL){
  354.       if(!quietFlag) fprintf(stderr,"unable to alloc video stream");
  355.     exit(1);
  356.   }
  357.  
  358.   mpegVidRsrc(0, theStream);
  359.   
  360.   if (firstLoop) {
  361.       InitDisplay(curVidStream->h_size, curVidStream->v_size);
  362.  //InitDisplay(curVidStream->mb_width*16, curVidStream->v_size);
  363.  
  364.       /* set up timing information */
  365.       frames_per_sec = 1.0*curVidStream->picture_rate;
  366.     frame_interval = 1.0/(1.0*curVidStream->picture_rate);  
  367.       frame_ref = curVidStream->picture.temp_ref;
  368.  
  369.       if(!speedFlag) printf("requested frames/sec = %d\n",
  370.                    curVidStream->picture_rate);
  371.   }
  372.   
  373.       realTimeStart = ReadSysClock();
  374.       next_time = ReadSysClock();
  375.   
  376.   while (1) { 
  377.     if(ReadSysClock() < next_time) {
  378.               if( (do_frame == 1) || speedFlag){
  379.                 /* do another frame */
  380.                 frame_ref = curVidStream->picture.temp_ref;
  381.                 while(frame_ref == curVidStream->picture.temp_ref){
  382.                     mpegVidRsrc(0, theStream);
  383.                 }
  384.                 do_frame = 0;
  385.             }
  386.     }
  387.     else{
  388.         next_time = next_time + frame_interval;
  389.         do_frame = 1;
  390.     }
  391.   }
  392. }
  393.  
  394.  
  395. /*
  396.  *--------------------------------------------------------------
  397.  *
  398.  * usage --
  399.  *
  400.  *    Print mpeg_play usage
  401.  *
  402.  * Results:
  403.  *    None.
  404.  *
  405.  * Side effects:
  406.  *    exits with a return value -1
  407.  *
  408.  *--------------------------------------------------------------
  409.  */
  410.  
  411. void
  412. usage(s)
  413. char *s;    /* program name */
  414. {
  415.     fprintf(stderr, "Usage:\n");
  416.     fprintf(stderr, "mpeg_play\n");
  417.     fprintf(stderr, "          [-nob]\n");
  418.     fprintf(stderr, "          [-nop]\n");
  419.     fprintf(stderr, "          [-loop]\n");
  420.     fprintf(stderr, "          [-eachstat]\n");
  421.     fprintf(stderr, "          [-no_display]\n");
  422.     fprintf(stderr, "          [-mag #]\n");
  423.     fprintf(stderr, "          [-quiet]\n");
  424.     fprintf(stderr, "          file_name\n");
  425.     exit (-1);
  426. }
  427.  
  428.  
  429.  
  430. /*
  431.  *--------------------------------------------------------------
  432.  *
  433.  * DoDitherImage --
  434.  *
  435.  *    Called when image needs to be dithered. Selects correct
  436.  *      dither routine based on info in ditherType.
  437.  *
  438.  * Results:
  439.  *    None.
  440.  *
  441.  * Side effects:
  442.  *    None.
  443.  *
  444.  *--------------------------------------------------------------
  445.  */
  446.  
  447. void
  448. DoDitherImage(l, Cr, Cb, disp, h, w) 
  449. unsigned char *l, *Cr, *Cb, *disp;
  450. int h,w;
  451. {
  452.     ColorDitherImage(l, Cr, Cb, disp, h, w);
  453. }
  454.